<?php

/**
 * ws优化 ，基础类库
 * User: tommy
 * Date: 2018/7/24
 * Time: 14:14
 */
class Ws
{
    CONST wsHOST = "0.0.0.0";
    CONST wsPOST = 9501;

    public $ws = null;

    public function __construct()
    {
        $this->ws = new swoole_websocket_server("0.0.0.0", 9501);

        //task_worker_num task的进程数，一定要设置，不然无法启动task
        $this->ws->set(array(
            'worker_num' => 2,
            'task_worker_num' => 2,
        ));
        $this->ws->on("open", [$this, "onOpen"]);
        $this->ws->on("message", [$this, "onMessage"]);
        //task队列，需要一个task 一个finish
        $this->ws->on("task", [$this, "onTask"]);
        $this->ws->on("finish", [$this, "onFinish"]);

        $this->ws->on("close", [$this, "onClose"]);

        $this->ws->start();
    }

    /**
     * 监听ws连接事件
     * @param $ws
     * @param $request
     */
    public function onOpen($ws, $request)
    {
        var_dump($request->fd);
        //测试一个定时器,每2秒执行
        if ($request->fd == 1) {
            swoole_timer_tick(2000, function ($timer_id) {
                echo "ws里的定时2秒，timer_id:{$timer_id}\n";
            });
        }
    }

    /**
     * 监听ws消息事件
     * @param $ws
     * @param $frame
     */
    public function onMessage($ws, $frame)
    {
        echo "走了ws类里的onMessage开头:{$frame->data}\n";

        //假设这里有一段代码逻辑，非常耗时todo 10s,就需要task队列
        $data = array(
            'task' => 1,
            'fd' => $frame->fd,
        );
        $ws->task($data);

        //测试一个定时器,5秒后给客户端推送一条消息
        //use ($ws, $frame) 这是用的php里的包
        swoole_timer_after(5000, function () use ($ws, $frame) {
            echo "timer_after 5秒\n";
            $ws->push($frame->fd, 'ws类push过来的timer_after');
        });
        $ws->push($frame->fd, "这是ws类onMessage push过来的数据" . date("Y-m-d H:i:s"));
    }

    /**
     * @param $serv
     * @param $taskId
     * @param $workerId
     * @param $data  这个是onMessae 里面传递过来的
     * @return string
     */
    public function onTask($serv, $taskId, $workerId, $data)
    {
        print_r($data);
        //耗时场景 10s
        sleep(10);
        return "on task finish";//告诉worker
    }

    /**
     * @param $serv
     * @param $taskId
     * @param $data 这个是onTask return的内容
     */
    public function onFinish($serv, $taskId, $data)
    {
        echo "taskId:{$taskId}\n";
        echo "task onFinish:{$data}\n";
    }

    /**
     * 监听ws关闭事件
     * @param $ws
     * @param $fd
     */
    public function onClose($ws, $fd)
    {
        echo "客户id关闭:{$fd}\n";
    }
}

$obj = new Ws();